package org.fioma.tree.suffixTree.memory.ukkonen;

import java.util.ArrayList;

import org.fioma.tree.bytes.LabelRefBytesIndexFactory;
import org.fioma.tree.suffixTree.memory.SimpleSuffixTreeHandlerMemory;

public class SimpleUkkonenSuffixTreeHandlerMemory extends
		SimpleSuffixTreeHandlerMemory<UkkonenInternalSuffixNodeMemory, UkkonenLeafSuffixNodeMemory, UkkonenSuffixNodeMemory> {

	private ArrayList<SimpleUkkonenInternalSuffixNodeMemory> poolInternals = new ArrayList<SimpleUkkonenInternalSuffixNodeMemory>(100);
	private int nextInternalObject = 0;
	private ArrayList<SimpleUkkonenLeafSuffixNodeMemory> poolLeafs = new ArrayList<SimpleUkkonenLeafSuffixNodeMemory>(100);
	private int nextLeafObject = 0;

	public SimpleUkkonenSuffixTreeHandlerMemory(UkkonenMemory memory, LabelRefBytesIndexFactory labelFactory) {
		super(memory, labelFactory);
	}

	@Override
	public UkkonenInternalSuffixNodeMemory createInternalNode(long pos) {
		if (pos == 0) {
			return null;
		} else {
			return createInternalNodeObject(pos);
		}
	}

	@Override
	public UkkonenLeafSuffixNodeMemory createLeafNode(long pos) {
		if (pos == 0) {
			return null;
		} else {
			return createLeafNodeObject(pos);
		}
	}

	@Override
	public UkkonenSuffixNodeMemory[] createChildrenNodes() {
		return new UkkonenSuffixNodeMemory[4];
	}

	@Override
	public UkkonenMemory getMemory() {
		return (UkkonenMemory) memory;
	}

	private SimpleUkkonenInternalSuffixNodeMemory createInternalNodeObject(long pos) {
		SimpleUkkonenInternalSuffixNodeMemory ret;
		if (nextInternalObject < poolInternals.size()) {
			ret = poolInternals.get(nextInternalObject);
			nextInternalObject++;
			ret.setPos(pos);
		} else {
			ret = new SimpleUkkonenInternalSuffixNodeMemory(pos, this);
			poolInternals.add(ret);
			nextInternalObject++;
		}
		return ret;
	}

	private SimpleUkkonenLeafSuffixNodeMemory createLeafNodeObject(long pos) {
		SimpleUkkonenLeafSuffixNodeMemory ret;
		if (nextLeafObject < poolLeafs.size()) {
			ret = poolLeafs.get(nextLeafObject);
			nextLeafObject++;
			ret.setPos(pos);
		} else {
			ret = new SimpleUkkonenLeafSuffixNodeMemory(pos, this);
			poolLeafs.add(ret);
			nextLeafObject++;
		}
		return ret;
	}

	public void freeObjects() {
		nextInternalObject = 0;
		nextLeafObject = 0;
	}

}
